package com.ks.component.pay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.ks.common.enums.BizCodeEnum;
import com.ks.common.enums.ClientType;
import com.ks.common.exception.BizException;
import com.ks.common.model.PayInfoVO;
import com.ks.config.AliPayConfig;
import com.ks.config.AliPayUrlConfig;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * 阿里支付策略
 *
 * @author KingAusten
 * @date 2022/08/18 16:16:11
 */
@Service
@Slf4j
@AllArgsConstructor
public class AliPayStrategy implements PayStrategy{

    private final AliPayUrlConfig payUrlConfig;

    /**
     * 统一下单接口
     *
     * @param payInfoVO
     *
     * @return
     */
    @Override
    public String unifiedOrder(PayInfoVO payInfoVO){

        HashMap<String,String> content = new HashMap<>();
        //商户订单号,64个字符以内、可包含字母、数字、下划线；需保证在商户端不重复
        content.put("out_trade_no",payInfoVO.getOutTradeNo());
        content.put("product_code","FAST_INSTANT_TRADE_PAY");
        //订单总金额，单位为元，精确到小数点后两位
        content.put("total_amount",payInfoVO.getPayFee()
                .toString());
        //商品标题/交易标题/订单标题/订单关键字等。 注意：不可使用特殊字符，如 /，=，&amp; 等。
        content.put("subject",payInfoVO.getTitle());
        //商品描述，可空
        content.put("body",payInfoVO.getDescription());

        double timeout = Math.floor(payInfoVO.getOrderPayTimeoutMills() / (1000 * 60));

        //前端也需要判断订单是否要关闭了， 如果要快要到期则不给二次支付
        if(timeout < 1){throw new BizException(BizCodeEnum.PAY_ORDER_PAY_TIMEOUT);}
        // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        content.put("timeout_express",Double.valueOf(timeout)
                .intValue() + "m");

        String clientType = payInfoVO.getClientType();
        String form = "";

        try{

            if(clientType.equalsIgnoreCase(ClientType.H5.name())){
                //H5手机网页支付
                AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
                request.setBizContent(JSON.toJSONString(content));
                request.setNotifyUrl(payUrlConfig.getAlipayCallbackUrl());
                request.setReturnUrl(payUrlConfig.getAlipaySuccessReturnUrl());
                AlipayTradeWapPayResponse alipayResponse = AliPayConfig.getInstance()
                        .pageExecute(request);

                log.info("响应日志:alipayResponse={}",alipayResponse);
                if(alipayResponse.isSuccess()){
                    form = alipayResponse.getBody();
                }else{
                    log.error("支付宝构建H5表单失败:alipayResponse={},payInfo={}",alipayResponse,payInfoVO);
                }

            }else if(clientType.equalsIgnoreCase(ClientType.PC.name())){
                //PC支付
                AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
                request.setBizContent(JSON.toJSONString(content));
                request.setNotifyUrl(payUrlConfig.getAlipayCallbackUrl());
                request.setReturnUrl(payUrlConfig.getAlipaySuccessReturnUrl());
                AlipayTradePagePayResponse alipayResponse = AliPayConfig.getInstance()
                        .pageExecute(request);

                log.info("响应日志:alipayResponse={}",alipayResponse);

                if(alipayResponse.isSuccess()){
                    form = alipayResponse.getBody();
                }else{
                    log.error("支付宝构建PC表单失败:alipayResponse={},payInfo={}",alipayResponse,payInfoVO);
                }

            }

        }
        catch(AlipayApiException e){
            log.error("支付宝构建表单异常:payInfo={},异常={}",payInfoVO,e);
        }
        return form;
    }

    /**
     * 退款接口
     *
     * @param payInfoVO
     *
     * @return
     */
    @Override
    public String refund(PayInfoVO payInfoVO){

        return PayStrategy.super.refund(payInfoVO);
    }

    /**
     * 查询支付状态
     *
     * @param payInfoVO
     *
     * @return
     */
    @Override
    public String queryPayStatus(PayInfoVO payInfoVO){


        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        HashMap<String,String> content = new HashMap<>();

        //订单商户号,64位
        content.put("out_trade_no",payInfoVO.getOutTradeNo());
        request.setBizContent(JSON.toJSONString(content));

        AlipayTradeQueryResponse response = null;
        try{
            response = AliPayConfig.getInstance()
                    .execute(request);
            log.info("支付宝订单查询响应：{}",response.getBody());

        }
        catch(AlipayApiException e){
            log.error("支付宝订单查询异常:{ }",e);
        }

        if(response.isSuccess()){
            log.info("支付宝订单状态查询成功:{}",payInfoVO);
            return response.getTradeStatus();
        }else{
            log.info("支付宝订单状态查询失败:{}",payInfoVO);
            return "";
        }
    }

    /**
     * 关闭订单
     *
     * @param payInfoVO
     *
     * @return
     */
    @Override
    public String closeOrder(PayInfoVO payInfoVO){

        return PayStrategy.super.closeOrder(payInfoVO);
    }

}
